<?php
/**
 * 
 * @author yusaint
 * @since 2014-3-9
 * @project Pfinal
 */
class Pfinal_Model_Optimizer_Default implements Pfinal_Model_Optimizer_Interface{
	
	/**
	 * 优化的规则，支持不跨库的查询join合并，比方说
	 * 	selectorA->leftJoin(SelectorB)->fullJoin(SelectorC)
	 * 	---------------------------------------------------优化后
	 *  selectOptimized,已经包含了整个查询的join关系
	 *  在query的时候，将这个selector protocolParse一下即可
	 * @see BaseOptimizer::optimize()
	 */
	public function optimize(Pfinal_Model_SelectorChain &$chain){
		$optimizedChain=new Pfinal_Model_SelectorChain();
		$optimizedChain->setCount($chain->getCount());
		$optimizedChain->setOffset($chain->getOffset());
		$optimizedChain->setOrderBy($chain->getOrderBy());
		$optimizedChain->setOrder($chain->getOrder());
		$optimizedChain->setFilterStack($chain->getFilterStack());

// 		if(count($chain)===1){
// 			$head=current(reset($chain));
// 			if($head->getAdapter() instanceof Pfinal_Model_Adapter_RMDBS){
// 				foreach ($chain as $selector) {
// 					$selector
// 						->limit($chain->getCount(),$chain->getOffset())
// 						->orderBy($chain->getOrderBy(),$chain->getOrder());
// 					$optimizedChain->start($selector);
// 				}
// 				return $optimizedChain;
// 			}
// 		}
		//首先遍历chain，合并所有adapter都是RMDBSAdapter，并且database都是一个的selector合并
		//单表查询的时候，可以将limit和orderby参数传入selector
		$pre=null;
		$current=null;
		foreach ($chain as $selector) {
			$current=$selector;
			$adapter=$current->getAdapter();
			if($adapter instanceof Pfinal_Model_Adapter_RMDBS){
				if(is_null($pre)){
					$pre=$selector;
					continue;
				}
				else{
					if($pre instanceof Pfinal_Model_Selector&&$pre->getAdapter()->RMDBSSignature()===$current->getAdapter()->RMDBSSignature()){
						//满足同一个数据库的查询，才能join，否则只能通过代码来join，不能直接在sql中join
						//不支持跨库join
						$pre->join($current);
					}else{
						if(!is_null($pre)){
							$pre->limit($chain->getCount(),$chain->getOffset());
							$pre->orderBy($chain->getOrderBy(),$chain->getOrder());
							$this->merge($optimizedChain, $pre);					
						}
						//去掉doris请求的分页排序条件
						$current->limit(0,0);
						//$current->orderBy(NULL,NULL);
						$this->merge($optimizedChain, $current);				
						$current=null;
						$pre=null;		
					}
				}
			}else{
				if(!is_null($pre)){//本次能合并的所有re的selector都已经合并，还原limit等参数
					$pre->limit($chain->getCount(),$chain->getOffset());
					$pre->orderBy($chain->getOrderBy(),$chain->getOrder());
					$this->merge($optimizedChain, $pre);					
				}
				//去掉doris请求的分页排序条件
				$current->limit(0,0);
				//$current->orderBy(NULL,NULL);
				$this->merge($optimizedChain, $current);				
				$current=null;
				$pre=null;							
			}					
		}
		if(!is_null($pre)){
			//修正ReportEngine请求的limit和count参数
			$pre->limit($chain->getCount(),$chain->getOffset());
			$pre->orderBy($chain->getOrderBy(),$chain->getOrder());
			$this->merge($optimizedChain, $pre);
		}		
		return $optimizedChain;
		
	}
	
	/**
	 *
	 * @param SelectorChain $chain
	 * @param Selector $selector
	 */
	protected function merge(Pfinal_Model_SelectorChain &$chain,Pfinal_Model_Selector $selector){
		if(count($chain)===0){
			$chain->start($selector);
		}else{
			switch ($selector->getPre()){
				case Pfinal_Model_SelectorChain::OPT_FULL_JOIN:
					$chain->fullJoin($selector);
					break;
				case Pfinal_Model_SelectorChain::OPT_LEFT_JOIN:
					$chain->leftJoin($selector);
					break;
				case Pfinal_Model_SelectorChain::OPT_INNER_JOIN:
					$chain->innerJoin($selector);
					break;
				case Pfinal_Model_SelectorChain::OPT_UNION:
					$chain->union($selector);
					break;
				default:
					$errMsg=sprintf('unexpected selector in selectorChain,Selector Type is expected');					
					throw new Pfinal_Exception_Runtime($errMsg);
			}
		}
	}
}